<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

  
  <title>177230_23种设计模式详解笔记Part1 | 个人博客</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="零、讲在前面1.学习基础要求：（1）对JavaEE尤其面向对象思想有较为深刻的理解和使用经验； （2）熟练掌握eclipse或idea使用； （3）对Java有良好的编程习惯。 2.课程说明：​    本课程主要讲解设计模式思想，对于开发工具使用、语法、编程习惯、代码细节不做过多讲解。 ​    课程使用环境及工具：jdk1.8 + idea2018.2.4 3.课程介绍一、设计模式概述1.设计模">
<meta property="og:type" content="article">
<meta property="og:title" content="177230_23种设计模式详解笔记Part1">
<meta property="og:url" content="http://codercheng.cn/2020/08/24/177230_23%E7%A7%8D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E8%AF%A6%E8%A7%A3%E7%AC%94%E8%AE%B0Part1/index.html">
<meta property="og:site_name" content="个人博客">
<meta property="og:description" content="零、讲在前面1.学习基础要求：（1）对JavaEE尤其面向对象思想有较为深刻的理解和使用经验； （2）熟练掌握eclipse或idea使用； （3）对Java有良好的编程习惯。 2.课程说明：​    本课程主要讲解设计模式思想，对于开发工具使用、语法、编程习惯、代码细节不做过多讲解。 ​    课程使用环境及工具：jdk1.8 + idea2018.2.4 3.课程介绍一、设计模式概述1.设计模">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://codercheng.cn/.cn//C:%5CUsers%5Clenovo%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1554254661859.png">
<meta property="og:image" content="https://img-my.csdn.net/uploads/201211/29/1354156868_1191.PNG">
<meta property="og:image" content="https://img-my.csdn.net/uploads/201211/29/1354158145_2392.PNG">
<meta property="og:image" content="https://img-my.csdn.net/uploads/201211/29/1354159363_7245.PNG">
<meta property="og:image" content="http://codercheng.cn/.cn//C:%5CUsers%5Clenovo%5CDesktop%5Cdesign(net)%5Cassets%5C1554366555020.png">
<meta property="og:image" content="http://codercheng.cn/.cn//C:%5CUsers%5Clenovo%5CDesktop%5Cdesign(net)%5Cassets%5C1554366685054.png">
<meta property="og:image" content="http://codercheng.cn/.cn//builder.png">
<meta property="og:image" content="http://codercheng.cn/.cn//bike.png">
<meta property="og:image" content="http://codercheng.cn/.cn//bikebuilder.png">
<meta property="article:published_time" content="2020-08-24T11:29:00.462Z">
<meta property="article:modified_time" content="2021-03-03T07:29:21.819Z">
<meta property="article:author" content="CoderCheng">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://codercheng.cn/.cn//C:%5CUsers%5Clenovo%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1554254661859.png">
  
    <link rel="alternate" href="/atom.xml" title="个人博客" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  
    <link href="//fonts.lug.ustc.edu.cn/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  
<link rel="stylesheet" href="/css/style.css">

<meta name="generator" content="Hexo 4.2.1"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">个人博客</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="搜索"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://codercheng.cn"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main"><article id="post-177230_23种设计模式详解笔记Part1" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/08/24/177230_23%E7%A7%8D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E8%AF%A6%E8%A7%A3%E7%AC%94%E8%AE%B0Part1/" class="article-date">
  <time datetime="2020-08-24T11:29:00.462Z" itemprop="datePublished">2020-08-24</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">设计模式</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      177230_23种设计模式详解笔记Part1
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h1 id="零、讲在前面"><a href="#零、讲在前面" class="headerlink" title="零、讲在前面"></a>零、讲在前面</h1><h2 id="1-学习基础要求："><a href="#1-学习基础要求：" class="headerlink" title="1.学习基础要求："></a>1.学习基础要求：</h2><p>（1）对JavaEE尤其面向对象思想有较为深刻的理解和使用经验；</p>
<p>（2）熟练掌握eclipse或idea使用；</p>
<p>（3）对Java有良好的编程习惯。</p>
<h2 id="2-课程说明："><a href="#2-课程说明：" class="headerlink" title="2.课程说明："></a>2.课程说明：</h2><p>​    本课程主要讲解设计模式思想，对于开发工具使用、语法、编程习惯、代码细节不做过多讲解。</p>
<p>​    课程使用环境及工具：jdk1.8 + idea2018.2.4</p>
<h3 id="3-课程介绍"><a href="#3-课程介绍" class="headerlink" title="3.课程介绍"></a>3.课程介绍</h3><h1 id="一、设计模式概述"><a href="#一、设计模式概述" class="headerlink" title="一、设计模式概述"></a>一、设计模式概述</h1><h2 id="1-设计模式概念："><a href="#1-设计模式概念：" class="headerlink" title="1.设计模式概念："></a>1.设计模式概念：</h2><p>​    设计模式（Design Pattern）是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。</p>
<p>​    使用设计模式的目的：为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化；设计模式是软件工程的基石脉络，如同大厦的结构一样。</p>
<h2 id="2-设计模式简介："><a href="#2-设计模式简介：" class="headerlink" title="2.设计模式简介："></a>2.设计模式简介：</h2><p>​    设计模式（Design pattern）代表了最佳的实践，通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。</p>
<p>​    设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问，设计模式于己于他人于系统都是多赢的，设计模式使代码编制真正工程化，设计模式是软件工程的基石，如同大厦的一块块砖石一样。项目中合理地运用设计模式可以完美地解决很多问题，每种模式在现实中都有相应的原理来与之对应，每种模式都描述了一个在我们周围不断重复发生的问题，以及该问题的核心解决方案，这也是设计模式能被广泛应用的原因。</p>
<h2 id="3-六大设计原则："><a href="#3-六大设计原则：" class="headerlink" title="3.六大设计原则："></a>3.六大设计原则：</h2><p>为什么要提倡“Design Pattern”呢？根本原因是为了代码复用，增加可维护性。那么怎么才能实现代码复用呢？面向对象有几个原则：<a href="https://baike.baidu.com/item/%E5%8D%95%E4%B8%80%E8%81%8C%E8%B4%A3%E5%8E%9F%E5%88%99" target="_blank" rel="noopener">单一职责原则</a> （Single Responsiblity Principle SRP）<a href="https://baike.baidu.com/item/%E5%BC%80%E9%97%AD%E5%8E%9F%E5%88%99" target="_blank" rel="noopener">开闭原则</a>（Open Closed Principle，OCP）、<a href="https://baike.baidu.com/item/%E9%87%8C%E6%B0%8F%E4%BB%A3%E6%8D%A2%E5%8E%9F%E5%88%99" target="_blank" rel="noopener">里氏代换原则</a>（Liskov Substitution Principle，LSP）、<a href="https://baike.baidu.com/item/%E4%BE%9D%E8%B5%96%E5%80%92%E8%BD%AC%E5%8E%9F%E5%88%99" target="_blank" rel="noopener">依赖倒转原则</a>（Dependency Inversion Principle，DIP）、<a href="https://baike.baidu.com/item/%E6%8E%A5%E5%8F%A3%E9%9A%94%E7%A6%BB%E5%8E%9F%E5%88%99" target="_blank" rel="noopener">接口隔离原则</a>（Interface Segregation Principle，ISP）、合成/聚合复用原则（Composite/Aggregate Reuse Principle，CARP）、最小知识原则（Principle of Least Knowledge，PLK，也叫<a href="https://baike.baidu.com/item/%E8%BF%AA%E7%B1%B3%E7%89%B9%E6%B3%95%E5%88%99" target="_blank" rel="noopener">迪米特法则</a>）。开闭原则具有理想主义的色彩，它是面向对象设计的终极目标。其他几条，则可以看做是开闭原则的实现方法。</p>
<h3 id="（1）总原则：开闭原则（Open-Close-Principle）"><a href="#（1）总原则：开闭原则（Open-Close-Principle）" class="headerlink" title="（1）总原则：开闭原则（Open Close Principle）"></a>（1）总原则：开闭原则（Open Close Principle）</h3><p>​    开闭原则就是说对扩展开放，对修改关闭。在程序需要进行拓展的时候，不能去修改原有的代 码，而是要扩展原有代码，实现一个热插拔的效果。所以一句话概括就是：为了使程序的扩展性好，易于维护和升级。想要达到这样的效果，我们需要使用接口和抽象类等，后面的具体设计中我们会提到这点。 单一职责原则不要存在多于一个导致类变更的原因，也就是说每个类应该实现单一的职责，如若不然，就应该把类拆分。 </p>
<h3 id="（2）里氏替换原则（Liskov-Substitution-Principle）"><a href="#（2）里氏替换原则（Liskov-Substitution-Principle）" class="headerlink" title="（2）里氏替换原则（Liskov Substitution Principle）"></a>（2）里氏替换原则（Liskov Substitution Principle）</h3><p>​    里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说，任何基类可以出现的地方，子类一定可以出现。 LSP 是继承复用的基石，只有当衍生类可以替换掉基类，软件单位的功能不受到影响时，基类才能真正被复用，而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现，所以里氏代换原则是对实 现抽象化的具体步骤的规范。里氏替换原则中，子类对父类的方法尽量不要重写和重载。因为父类代表了定义好的结构，通过这个规范的接口与外界交互，子类不应该随便破坏它。</p>
<h3 id="（3）依赖倒转原则（Dependence-Inversion-Principle）"><a href="#（3）依赖倒转原则（Dependence-Inversion-Principle）" class="headerlink" title="（3）依赖倒转原则（Dependence Inversion Principle）"></a>（3）依赖倒转原则（Dependence Inversion Principle）</h3><p>​    这个是开闭原则的基础，具体内容：面向接口编程，依赖于抽象而不依赖于具体。写代码时用到具体类时，不与具体类交互，而与具体类的上层接口交互。 </p>
<h3 id="（4）接口隔离原则（Interface-Segregation-Principle）"><a href="#（4）接口隔离原则（Interface-Segregation-Principle）" class="headerlink" title="（4）接口隔离原则（Interface Segregation Principle）"></a>（4）接口隔离原则（Interface Segregation Principle）</h3><p>​    这个原则的意思是：每个接口中不存在子类用不到却必须实现的方法，如果不然，就要将接口 拆分。使用多个隔离的接口，比使用单个接口（多个接口方法集合到一个的接口）要好。</p>
<h3 id="（5）迪米特法则（最少知道原则）（Demeter-Principle）"><a href="#（5）迪米特法则（最少知道原则）（Demeter-Principle）" class="headerlink" title="（5）迪米特法则（最少知道原则）（Demeter Principle）"></a>（5）迪米特法则（最少知道原则）（Demeter Principle）</h3><p>​    就是说：一个类对自己依赖的类知道的越少越好。也就是说无论被依赖的类多么复杂，都应该将逻辑封装方法的内部，通过 public 方法提供给外部。这样当被依赖的类变化时，才能最小的影响该类。 最少知道原则的另一个表达方式是：只与直接的朋友通信。类之间只要有耦合关系，就叫朋友关系。耦合分为依赖、关联、聚合、组合等。我们称出现为成员变量、方法参数、方法返回值中的类为直接朋友。局部变量、临时变量则不是直接的朋友。我们要求陌生的类不要作为局部 变量出现在类中。 </p>
<h3 id="（6）合成复用原则（Composite-Reuse-Principle）"><a href="#（6）合成复用原则（Composite-Reuse-Principle）" class="headerlink" title="（6）合成复用原则（Composite Reuse Principle）"></a>（6）合成复用原则（Composite Reuse Principle）</h3><p>​    原则是尽量首先使用合成/聚合的方式，而不是使用继承。 </p>
<h2 id="4-设计模式的分类："><a href="#4-设计模式的分类：" class="headerlink" title="4.设计模式的分类："></a>4.设计模式的分类：</h2><p>总体来说设计模式分为三大类：</p>
<p>创建型模式，共五种：工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。</p>
<p>结构型模式，共七种：适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。</p>
<p>行为型模式，共十一种：策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。</p>
<p>其实还有两类：并发型模式和线程池模式，以图的形式表示：</p>
<p><img src="/.cn//C:%5CUsers%5Clenovo%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1554254661859.png" alt="1554254661859"></p>
<a id="more"></a>


<h1 id="二-创建型模式（5种）"><a href="#二-创建型模式（5种）" class="headerlink" title="二.创建型模式（5种）"></a>二.创建型模式（5种）</h1><h2 id="0-简单工厂模式："><a href="#0-简单工厂模式：" class="headerlink" title="0.简单工厂模式："></a>0.简单工厂模式：</h2><p>​    简单工厂模式是属于创建型模式，但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式，可以理解为是不同工厂模式的一个特殊实现。简单工厂一般分为：普通简单工厂、多方法简单工厂、静态方法简单工厂。 </p>
<h3 id="0-1-普通简单工厂："><a href="#0-1-普通简单工厂：" class="headerlink" title="0.1 普通简单工厂："></a>0.1 普通简单工厂：</h3><p><img src="https://img-my.csdn.net/uploads/201211/29/1354156868_1191.PNG" alt="img"></p>
<p>举例如下：（我们举一个发送邮件和短信的例子）</p>
<p>首先，创建二者的共同接口：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Sender</span> </span>&#123;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">Send</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>其次，创建实现类：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MailSender</span> <span class="keyword">implements</span> <span class="title">Sender</span> </span>&#123;</span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">Send</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		System.out.println(<span class="string">"this is mailsender!"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SmsSender</span> <span class="keyword">implements</span> <span class="title">Sender</span> </span>&#123;</span><br><span class="line"> </span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">Send</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		System.out.println(<span class="string">"this is sms sender!"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>最后，建工厂类：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SendFactory</span> </span>&#123;</span><br><span class="line"> </span><br><span class="line">	<span class="function"><span class="keyword">public</span> Sender <span class="title">produce</span><span class="params">(String type)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">if</span> (<span class="string">"mail"</span>.equals(type)) &#123;</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">new</span> MailSender();</span><br><span class="line">		&#125; <span class="keyword">else</span> <span class="keyword">if</span> (<span class="string">"sms"</span>.equals(type)) &#123;</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">new</span> SmsSender();</span><br><span class="line">		&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">			System.out.println(<span class="string">"请输入正确的类型!"</span>);</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>我们来测试下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">FactoryTest</span> </span>&#123;</span><br><span class="line"> </span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		SendFactory factory = <span class="keyword">new</span> SendFactory();</span><br><span class="line">		Sender sender = factory.produce(<span class="string">"sms"</span>);</span><br><span class="line">		sender.Send();</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出：this is sms sender!</p>
<h3 id="0-2-多方法简单工厂："><a href="#0-2-多方法简单工厂：" class="headerlink" title="0.2 多方法简单工厂："></a>0.2 多方法简单工厂：</h3><p><img src="https://img-my.csdn.net/uploads/201211/29/1354158145_2392.PNG" alt="img"></p>
<p>将上面的代码做下修改，改动下SendFactory类就行，如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SendFactory</span> </span>&#123;</span><br><span class="line">	</span><br><span class="line">	<span class="function"><span class="keyword">public</span> Sender <span class="title">produceMail</span><span class="params">()</span></span>&#123;</span><br><span class="line">		<span class="keyword">return</span> <span class="keyword">new</span> MailSender();</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	<span class="function"><span class="keyword">public</span> Sender <span class="title">produceSms</span><span class="params">()</span></span>&#123;</span><br><span class="line">		<span class="keyword">return</span> <span class="keyword">new</span> SmsSender();</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>测试类如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">FactoryTest</span> </span>&#123;</span><br><span class="line"> </span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		SendFactory factory = <span class="keyword">new</span> SendFactory();</span><br><span class="line">		Sender sender = factory.produceMail();</span><br><span class="line">		sender.Send();</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出：this is mailsender!</p>
<h3 id="0-3-静态方法简单工厂："><a href="#0-3-静态方法简单工厂：" class="headerlink" title="0.3 静态方法简单工厂："></a>0.3 静态方法简单工厂：</h3><p>将上面的多个工厂方法模式里的方法置为静态的，不需要创建实例，直接调用即可。 </p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">FactoryTest</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        SendFactory factory = <span class="keyword">new</span> SendFactory();</span><br><span class="line">        Sender sender = factory.produceMail();</span><br><span class="line">        sender.Send();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">FactoryTest</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Sender sender = SendFactory.produceMail(); </span><br><span class="line">        sender.Send();  </span><br><span class="line">    &#125;  </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>​    输出：this is mailsender!</p>
<h3 id="0-4-简单工厂模式的优缺点："><a href="#0-4-简单工厂模式的优缺点：" class="headerlink" title="0.4 简单工厂模式的优缺点："></a>0.4 简单工厂模式的优缺点：</h3><p>优点：</p>
<ul>
<li>很明显，简单工厂的特点就是“简单粗暴”，通过一个含参的工厂方法，我们可以实例化任何产品类，上至飞机火箭，下至土豆面条，无所不能。所以简单工厂有一个别名：上帝类。</li>
</ul>
<p>缺点：</p>
<ul>
<li>任何”东西“的子类都可以被生产，负担太重。当所要生产产品种类非常多时，工厂方法的代码量可能会很庞大</li>
<li>在遵循开闭原则（对拓展开放，对修改关闭）的条件下，简单工厂对于增加新的产品，无能为力。因为增加新产品只能通过修改工厂方法来实现。</li>
</ul>
<h2 id="1-工厂方法模式："><a href="#1-工厂方法模式：" class="headerlink" title="1.工厂方法模式："></a>1.工厂方法模式：</h2><h3 id="1-1-理解："><a href="#1-1-理解：" class="headerlink" title="1.1 理解："></a>1.1 理解：</h3><p>​    简单工厂模式有一个问题就是，类的创建依赖工厂类，也就是说，如果想要拓展程序，必须对工厂类进行修改，这违背了开闭原则，所以，从设计角度考虑，有一定的问题，如何解决？就用到工厂方法模式，创建一个工厂接口和创建多个工厂实现类，这样一旦需要增加新的功能， 直接增加新的工厂类就可以了，不需要修改之前的代码。 </p>
<h3 id="1-2-代码案例："><a href="#1-2-代码案例：" class="headerlink" title="1.2 代码案例："></a>1.2 代码案例：</h3><p><img src="https://img-my.csdn.net/uploads/201211/29/1354159363_7245.PNG" alt="img"></p>
<p><img src="/.cn//C:%5CUsers%5Clenovo%5CDesktop%5Cdesign(net)%5Cassets%5C1554366555020.png" alt="1554366555020"></p>
<p>Sender接口、SmsSender类、MailSender类同简单工厂，无需修改。</p>
<p>创建Provider接口，produce()抽象方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Provider</span> </span>&#123;</span><br><span class="line">    <span class="function">Sender <span class="title">produce</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>创建Provider接口的实现类：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MailSenderFactory</span> <span class="keyword">implements</span> <span class="title">Provider</span></span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Sender <span class="title">produce</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> MailSender();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SmsSenderFactory</span> <span class="keyword">implements</span> <span class="title">Provider</span></span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Sender <span class="title">produce</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> SmsSender();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="1-3-工厂方法模式的优缺点："><a href="#1-3-工厂方法模式的优缺点：" class="headerlink" title="1.3 工厂方法模式的优缺点："></a>1.3 工厂方法模式的优缺点：</h3><p>优点：</p>
<ul>
<li>工厂方法模式就很好的减轻了工厂类的负担，把某一类/某一种东西交由一个工厂生产；（对应简单工厂的缺点1）</li>
<li>同时增加某一类”东西“并不需要修改工厂类，只需要添加生产这类”东西“的工厂即可，使得工厂类符合开闭原则。</li>
</ul>
<p>缺点：</p>
<ul>
<li>相比简单工厂，实现略复杂。</li>
<li>对于某些可以形成产品族的情况处理比较复杂（相对抽象工厂）。</li>
</ul>
<h2 id="2-抽象工厂模式："><a href="#2-抽象工厂模式：" class="headerlink" title="2.抽象工厂模式："></a>2.抽象工厂模式：</h2><h3 id="2-1-理解："><a href="#2-1-理解：" class="headerlink" title="2.1 理解："></a>2.1 理解：</h3><p>​    抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时，使用的一种工厂模式。<strong>抽象工厂模式可以向客户端提供一个接口，使客户端在不必指定产品的具体的情况下，创建多个<em>产品族</em>中的产品对象</strong>。根据里氏替换原则，任何接受父类型的地方，都应当能够接受子类型。因此，实际上系统所需要的，仅仅是类型与这些抽象产品角色相同的一些实例，而不是这些抽象产品的实例。换言之，也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。</p>
<h3 id="2-2-代码案例："><a href="#2-2-代码案例：" class="headerlink" title="2.2  代码案例："></a>2.2  代码案例：</h3><p><img src="/.cn//C:%5CUsers%5Clenovo%5CDesktop%5Cdesign(net)%5Cassets%5C1554366685054.png" alt="1554366685054"></p>
<p>Sender接口、SmsSender类、MailSender类同简单工厂，无需修改。</p>
<p>与Sender接口与实现类相似，创建Call接口及其实现类WXCall、QQCall，并创建call()方法，实现类对其进行重写：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Call</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">call</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">QQCall</span> <span class="keyword">implements</span> <span class="title">Call</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">call</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"This is QQCall"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">WXCall</span> <span class="keyword">implements</span> <span class="title">Call</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">call</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"This is WXCall"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>创建产品族工厂接口ProviderPlus，编写创建Call、Sender接口实现类对象的方法produceCall()、produceSender()：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">ProviderPlus</span> </span>&#123;</span><br><span class="line">    <span class="function">Call <span class="title">produceCall</span><span class="params">()</span></span>;</span><br><span class="line">    <span class="function">Sender <span class="title">produceSender</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>创建ProviderPlus接口实现类，即产品族工厂：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Phone1Factory</span> <span class="keyword">implements</span> <span class="title">ProviderPlus</span></span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Call <span class="title">produceCall</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> QQCall();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Sender <span class="title">produceSender</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> MailSender();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Phone2Factory</span> <span class="keyword">implements</span>  <span class="title">ProviderPlus</span></span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Call <span class="title">produceCall</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> WXCall();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Sender <span class="title">produceSender</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> SmsSender();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>测试类：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Test</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Phone1Factory phone1Factory = <span class="keyword">new</span> Phone1Factory();</span><br><span class="line">        Call call = phone1Factory.produceCall();</span><br><span class="line">        Sender sender = phone1Factory.produceSender();</span><br><span class="line">        call.call();</span><br><span class="line">        sender.send();</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">"============================"</span>);</span><br><span class="line"></span><br><span class="line">        Phone2Factory phone2Factory = <span class="keyword">new</span> Phone2Factory();</span><br><span class="line">        Call call1 = phone2Factory.produceCall();</span><br><span class="line">        Sender sender1 = phone2Factory.produceSender();</span><br><span class="line">        call1.call();</span><br><span class="line">        sender1.send();</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="2-3-抽象工厂模式的优缺点："><a href="#2-3-抽象工厂模式的优缺点：" class="headerlink" title="2.3 抽象工厂模式的优缺点："></a>2.3 抽象工厂模式的优缺点：</h3><p>​    优点： </p>
<ul>
<li>抽象工厂模式隔离了具体类的生产，使得客户并不需要知道什么被创建。</li>
<li>当一个产品族中的多个对象被设计成一起工作时，它能保证客户端始终只使用同一个产品族中的对象。</li>
<li>增加新的具体工厂和产品族很方便，无须修改已有系统，符合“开闭原则”。</li>
</ul>
<p>​        缺点：</p>
<ul>
<li>增加新的产品等级结构很复杂，需要修改抽象工厂和所有的具体工厂类。</li>
</ul>
<h2 id="3-单例模式："><a href="#3-单例模式：" class="headerlink" title="3.单例模式："></a>3.单例模式：</h2><h3 id="3-1-理解："><a href="#3-1-理解：" class="headerlink" title="3.1 理解："></a>3.1 理解：</h3><p>​    单例模式（Singleton Pattern）是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式，它提供了一种创建对象的最佳方式。</p>
<p>​    这种模式涉及到一个单一的类，该类负责创建自己的对象，同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式，可以直接访问，不需要实例化该类的对象。</p>
<h3 id="3-2-代码案例："><a href="#3-2-代码案例：" class="headerlink" title="3.2 代码案例："></a>3.2 代码案例：</h3><h4 id="a-饿汉模式："><a href="#a-饿汉模式：" class="headerlink" title="(a)饿汉模式："></a>(a)饿汉模式：</h4><p>​    这种方式是最基本的实现方式，这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized，所以严格意义上它并不算单例模式。</p>
<p>这种方式 lazy loading 很明显，不要求线程安全，在多线程不能正常工作。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Person1</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 1.将构造方法私有——防止外界创建对象</span></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="title">Person1</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">super</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 2.创建自己的对象</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> Person1 person1 = <span class="keyword">new</span> Person1();</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 3.给外界访问方式</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Person1 <span class="title">getInstance</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">return</span> person1;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h4 id="b-懒汉模式"><a href="#b-懒汉模式" class="headerlink" title="(b)懒汉模式:"></a>(b)懒汉模式:</h4><p>​    这种方式具备很好的 lazy loading，能够在多线程中很好的工作，但是，效率很低，99% 情况下不需要同步。<br>优点：第一次调用才初始化，避免内存浪费。<br>缺点：必须加锁 synchronized 才能保证单例，但加锁会影响效率。</p>
<p>getInstance() 的性能对应用程序不是很关键（该方法使用不太频繁）。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Person2</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 1.将构造方法私有——防止外界创建对象</span></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="title">Person2</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">super</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 2.创建自己的对象</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> Person2 person2;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     *  3.给外界访问方式</span></span><br><span class="line"><span class="comment">     *  (1)创建对象</span></span><br><span class="line"><span class="comment">     *  (2)之前已经被创建过，直接使用之前的对象</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Person2 <span class="title">getInstance</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(person2 == <span class="keyword">null</span>)&#123;<span class="comment">// 第一次创建时</span></span><br><span class="line">            person2 = <span class="keyword">new</span> Person2();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 如果之前已经被创建过，直接使用之前的对象</span></span><br><span class="line">        <span class="keyword">return</span> person2;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h4 id="c-懒汉模式-线程安全"><a href="#c-懒汉模式-线程安全" class="headerlink" title="(c)懒汉模式(线程安全):"></a>(c)懒汉模式(线程安全):</h4><p>​    这种方式比较常用，但容易产生垃圾对象。<br>优点：没有加锁，执行效率会提高。<br>缺点：类加载时就初始化，浪费内存。<br>​    它基于 classloader 机制避免了多线程的同步问题，不过，instance 在类装载时就实例化，虽然导致类装载的原因有很多种，在单例模式中大多数都是调用 getInstance ()方法， 但是也不能确定有其他的方式（或者其他的静态方法）导致类装载，这时候初始化 instance 显然没有达到 lazy loading 的效果。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Person4</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 1.将构造方法私有——防止外界创建对象</span></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="title">Person4</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">super</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 2.创建自己的对象</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> Person4 person2;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     *  3.给外界访问方式</span></span><br><span class="line"><span class="comment">     *  方法添加线程锁synchronized保证线程安全</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">synchronized</span> Person4 <span class="title">getInstance</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(person2 == <span class="keyword">null</span>)&#123;<span class="comment">// 第一次创建时</span></span><br><span class="line">            person2 = <span class="keyword">new</span> Person4();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 如果之前已经被创建过，直接使用之前的对象</span></span><br><span class="line">        <span class="keyword">return</span> person2;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h4 id="d-懒汉模式-双重锁"><a href="#d-懒汉模式-双重锁" class="headerlink" title="(d)懒汉模式(双重锁):"></a>(d)懒汉模式(双重锁):</h4><p>​    这种方式采用双锁机制，安全且在多线程情况下能保持高性能。<br>getInstance() 的性能对应用程序很关键。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Person5</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 1.将构造方法私有——防止外界创建对象</span></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="title">Person5</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">super</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 2.创建自己的对象</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> Person5 person2;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     *  3.给外界访问方式</span></span><br><span class="line"><span class="comment">     *  (1)创建对象</span></span><br><span class="line"><span class="comment">     *  (2)之前已经被创建过，直接使用之前的对象</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Person5 <span class="title">getInstance</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(person2 == <span class="keyword">null</span>)&#123;</span><br><span class="line">            <span class="keyword">synchronized</span> (Person5<span class="class">.<span class="keyword">class</span>)</span>&#123;</span><br><span class="line">                <span class="keyword">if</span>(person2 == <span class="keyword">null</span>)&#123;</span><br><span class="line">                    person2 = <span class="keyword">new</span> Person5();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 如果之前已经被创建过，直接使用之前的对象</span></span><br><span class="line">        <span class="keyword">return</span> person2;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h4 id="e-登记式-静态内部类"><a href="#e-登记式-静态内部类" class="headerlink" title="(e)登记式/静态内部类:"></a>(e)登记式/静态内部类:</h4><p>​    这种方式能达到双检锁方式一样的功效，但实现更简单。对静态域使用延迟初始化，应使用这种方式而不是双检锁方式。这种方式只适用于静态域的情况，双检锁方式可在实例域需要延迟初始化时使用。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Person6</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 1.将构造方法私有——防止外界创建对象</span></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="title">Person6</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">super</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 2.创建自己的对象(内部类)</span></span><br><span class="line">   <span class="keyword">private</span> <span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">SinglePerson</span></span>&#123;</span><br><span class="line">        <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> Person6 PERSON = <span class="keyword">new</span> Person6();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     *  3.给外界访问方式</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Person6 <span class="title">getInstance</span><span class="params">()</span></span>&#123;</span><br><span class="line">         <span class="keyword">return</span> SinglePerson.PERSON;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="3-3-单例模式的优缺点："><a href="#3-3-单例模式的优缺点：" class="headerlink" title="3.3 单例模式的优缺点："></a>3.3 单例模式的优缺点：</h3><p>​    优点：</p>
<ul>
<li>1、某些类创建比较频繁，对于一些大型的对象，这是一笔很大的系统开销。 </li>
<li>2、省去了 new 操作符，降低了系统内存的使用频率，减轻 GC 压力。</li>
<li>3、有些类如交易所的核心交易引擎，控制着交易流程，如果该类可以创建多个的话，系统完 全乱了。（比如一个军队出现了多个司令员同时指挥，肯定会乱成一团），所以只有使用单例 模式，才能保证核心交易服务器独立控制整个流程</li>
</ul>
<p>​        缺点：</p>
<ul>
<li>没有接口，不能继承，与单一职责原则冲突，一个类应该只关心内部逻辑，而不关心外面怎么样来实例化。</li>
</ul>
<h2 id="4-建造者模式："><a href="#4-建造者模式：" class="headerlink" title="4.建造者模式："></a>4.建造者模式：</h2><h3 id="4-1-建造者模式概念："><a href="#4-1-建造者模式概念：" class="headerlink" title="4.1  建造者模式概念："></a>4.1  建造者模式概念：</h3><p>​    建造者模式很容易让人想到建房子，不管建刚需房、改善房还是别墅，它们都离不开地基、柱子、层面和墙体这些组成部分，建筑工人就是把这些组成部分一个个建起来，最后连成一体建出一栋栋楼房。</p>
<p>​    来看看建造者模式的定义，<strong>将一个复杂对象的构建与它的表示分离，使得同样的构建过程可以创建不同的表示</strong>。建房子的过程都是相似的，但可以建出形形色色的房子。</p>
<p><img src="/.cn//builder.png" alt="builder"></p>
<h3 id="5-2-代码案例："><a href="#5-2-代码案例：" class="headerlink" title="5.2 代码案例："></a>5.2 代码案例：</h3><p><img src="/.cn//bike.png" alt="bike"></p>
<p><img src="/.cn//bikebuilder.png" alt="bikebuilder"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Auther</span>: Xulu</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ProjectName</span>: Builder1Pattern</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2019/5/17 17:18</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:自行车类</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Bike</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 车架</span></span><br><span class="line">    <span class="keyword">private</span> String frame;</span><br><span class="line">    <span class="comment">// gps</span></span><br><span class="line">    <span class="keyword">private</span> String gps;</span><br><span class="line">    <span class="comment">// 轮胎</span></span><br><span class="line">    <span class="keyword">private</span> String tyre;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getFrame</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> frame;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setFrame</span><span class="params">(String frame)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.frame = frame;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getGps</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> gps;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setGps</span><span class="params">(String gps)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.gps = gps;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getTyre</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> tyre;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setTyre</span><span class="params">(String tyre)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.tyre = tyre;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">toString</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">"Bike&#123;"</span> +</span><br><span class="line">                <span class="string">"frame='"</span> + frame + <span class="string">'\''</span> +</span><br><span class="line">                <span class="string">", gps='"</span> + gps + <span class="string">'\''</span> +</span><br><span class="line">                <span class="string">", tyre='"</span> + tyre + <span class="string">'\''</span> +</span><br><span class="line">                <span class="string">'&#125;'</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Auther</span>: Xulu</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ProjectName</span>: Builder1Pattern</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2019/5/17 17:25</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:自行车生产线接口</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">BikeBuilder</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 组装轮胎</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">buildTyres</span><span class="params">()</span></span>;</span><br><span class="line">    <span class="comment">// 组装车架</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">buildFrame</span><span class="params">()</span></span>;</span><br><span class="line">    <span class="comment">// 装gps</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">buildGps</span><span class="params">()</span></span>;</span><br><span class="line">    <span class="comment">// 成品输出</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> Bike <span class="title">getBike</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Auther</span>: Xulu</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ProjectName</span>: Builder1Pattern</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2019/5/17 17:29</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:摩拜生产线</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MoBikeBuilder</span> <span class="keyword">implements</span> <span class="title">BikeBuilder</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> Bike bike = <span class="keyword">new</span> Bike();</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">buildTyres</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        bike.setTyre(<span class="string">"装非充气轮胎"</span>);</span><br><span class="line">        System.out.println(<span class="string">"装非充气轮胎"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">buildFrame</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        bike.setFrame(<span class="string">"装橙色车架"</span>);</span><br><span class="line">        System.out.println(<span class="string">"装橙色车架"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">buildGps</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        bike.setGps(<span class="string">"装MoBike的gps"</span>);</span><br><span class="line">        System.out.println(<span class="string">"装MoBike的gps"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Bike <span class="title">getBike</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> bike;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Auther</span>: Xulu</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ProjectName</span>: Builder1Pattern</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2019/5/17 17:32</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:ofo生产线</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">OfoBuilder</span> <span class="keyword">implements</span> <span class="title">BikeBuilder</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> Bike bike = <span class="keyword">new</span> Bike();</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">buildTyres</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        bike.setTyre(<span class="string">"装充气轮胎"</span>);</span><br><span class="line">        System.out.println(<span class="string">"装充气轮胎"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">buildFrame</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        bike.setFrame(<span class="string">"装明黄色车架"</span>);</span><br><span class="line">        System.out.println(<span class="string">"装明黄色车架"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">buildGps</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        bike.setGps(<span class="string">"装Ofo的gps"</span>);</span><br><span class="line">        System.out.println(<span class="string">"装Ofo的gps"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Bike <span class="title">getBike</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> bike;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Auther</span>: Xulu</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ProjectName</span>: Builder1Pattern</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2019/5/17 17:24</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:指挥者（工程部）</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">EnginnerDepartment</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 指定生产线</span></span><br><span class="line">    BikeBuilder bikeBuilder;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">EnginnerDepartment</span><span class="params">(BikeBuilder bikeBuilder)</span></span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.bikeBuilder = bikeBuilder;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 指导组装单车</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">construct</span><span class="params">()</span></span>&#123;</span><br><span class="line">        bikeBuilder.buildFrame();</span><br><span class="line">        bikeBuilder.buildTyres();</span><br><span class="line">        bikeBuilder.buildGps();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Auther</span>: Xulu</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ProjectName</span>: Builder1Pattern</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2019/5/17 17:37</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Test</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 生产ofo</span></span><br><span class="line">        OfoBuilder ofoBuilder = <span class="keyword">new</span> OfoBuilder();</span><br><span class="line">        EnginnerDepartment enginnerDepartment = <span class="keyword">new</span> EnginnerDepartment(ofoBuilder);</span><br><span class="line">        enginnerDepartment.construct();<span class="comment">// 指导组装</span></span><br><span class="line">        Bike ofoBuilderBike = ofoBuilder.getBike();</span><br><span class="line">        System.out.println(ofoBuilderBike);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 生产MoBike</span></span><br><span class="line">        MoBikeBuilder moBikeBuilder = <span class="keyword">new</span> MoBikeBuilder();</span><br><span class="line">        EnginnerDepartment enginnerDepartment1 = <span class="keyword">new</span> EnginnerDepartment(moBikeBuilder);</span><br><span class="line">        enginnerDepartment1.construct();</span><br><span class="line">        Bike moBikeBuilderBike = moBikeBuilder.getBike();</span><br><span class="line">        System.out.println(moBikeBuilderBike);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>







<h3 id="5-3-建造者模式优缺点："><a href="#5-3-建造者模式优缺点：" class="headerlink" title="5.3 建造者模式优缺点："></a>5.3 建造者模式优缺点：</h3><p>1.优点</p>
<p>　　（1）、产品的建造和表示分离，实现了解耦。</p>
<p>　　（2）、隐藏了产品的建造细节，用户只需关心产品的表示，而不需要了解是如何创建产品的。</p>
<p>　　（3）、体现了开闭原则，如上代码所示，如果需要再生产其他共享单车，只需要再开一条生产线即可，不影响其他生产线的作业。</p>
<p>　2.缺点</p>
<p>　　（1）、当建造者过多时，会产生很多类，难以维护。</p>
<p> 　<strong>建造者模式的使用场合是当创建复杂对象时，把创建对象成员和装配方法分离出来，放在建造者类中去实现，用户使用该复杂对象时，不用理会它的创建和装配过程，只关心它的表示形式。</strong>其实完全理解这个模式还是要一番思考的，难以搞懂的是指挥者似乎没什么存在的必要，在代码里也没体现它的作用，我们也可以把指挥者的方法放在建造者里面，但为什么没有这样做呢？我想这可能是考虑到单一责任原则，建造者只负责创建对象的各个部分，至于各个部分创建的顺序、装配方法它就不管了。还有就是当顺序要改变时，建造者可以不用改动，改动指挥者就好了，指挥者只有一个，建造者有很多，要改建造者就麻烦了。</p>
<h2 id="5-原型模式："><a href="#5-原型模式：" class="headerlink" title="5.原型模式："></a>5.原型模式：</h2><h3 id="5-1-原型模式概念："><a href="#5-1-原型模式概念：" class="headerlink" title="5.1 原型模式概念："></a>5.1 原型模式概念：</h3><p>​    原型模式（Prototype Pattern）是用于<strong>创建重复的对象</strong>，同时又能保证性能。这种类型的设计模式属于创建型模式，它提供了一种创建对象的最佳方式。</p>
<p>​    这种模式是实现了一个原型接口，该接口用于创建当前对象的<strong>克隆</strong>。当直接创建对象的代价比较大时，则采用这种模式。例如，一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象，在下一个请求时返回它的克隆，在需要的时候更新数据库，以此来减少数据库调用。</p>
<p>​    </p>
<h3 id="5-2-代码案例：-1"><a href="#5-2-代码案例：-1" class="headerlink" title="5.2 代码案例："></a>5.2 代码案例：</h3><p>以批量发送邮件为例：</p>
<p>AdvTemplete广告：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">AdvTemplete</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 广告信名称</span></span><br><span class="line">    <span class="keyword">private</span> String advSubject = <span class="string">"广告信名称"</span>;</span><br><span class="line">    <span class="comment">// 广告信内容</span></span><br><span class="line">    <span class="keyword">private</span> String advContent = <span class="string">"广告信内容"</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 获取广告信名称</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getAdvSubject</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> advSubject;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 获取广告信内容</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getAdvContent</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> advContent;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Mail类：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Mail</span> <span class="keyword">implements</span> <span class="title">Cloneable</span></span>&#123;</span><br><span class="line">    <span class="comment">// 售收件人</span></span><br><span class="line">    <span class="keyword">private</span> String receiver;</span><br><span class="line">    <span class="comment">// 邮件名称</span></span><br><span class="line">    <span class="keyword">private</span> String subject;</span><br><span class="line">    <span class="comment">// 称谓</span></span><br><span class="line">    <span class="keyword">private</span> String appellation;</span><br><span class="line">    <span class="comment">// 邮件内容</span></span><br><span class="line">    <span class="keyword">private</span> String content;</span><br><span class="line">    <span class="comment">// 邮件尾部</span></span><br><span class="line">    <span class="keyword">private</span> String tail;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> Mail <span class="title">clone</span><span class="params">()</span>  </span>&#123;</span><br><span class="line">        Mail mail = <span class="keyword">null</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            mail = (Mail) <span class="keyword">super</span>.clone();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (CloneNotSupportedException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> mail;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 构造方法</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> advTemplete</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Mail</span><span class="params">(AdvTemplete advTemplete)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.content = advTemplete.getAdvContent();</span><br><span class="line">        <span class="keyword">this</span>.subject = advTemplete.getAdvSubject();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// ======================setter,getter=======================================</span></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getReceiver</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> receiver;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setReceiver</span><span class="params">(String receiver)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.receiver = receiver;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getSubject</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> subject;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setSubject</span><span class="params">(String subject)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.subject = subject;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getAppellation</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> appellation;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setAppellation</span><span class="params">(String appellation)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.appellation = appellation;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getContent</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> content;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setContext</span><span class="params">(String content)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.content = content;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getTail</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> tail;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setTail</span><span class="params">(String tail)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.tail = tail;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 设置邮件发送数</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">int</span> MAX_COUNT = <span class="number">6</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     *  模拟邮件发送</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> args</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 邮件创建</span></span><br><span class="line">        Mail mail = <span class="keyword">new</span> Mail(<span class="keyword">new</span> AdvTemplete());</span><br><span class="line">        mail.setTail(<span class="string">"    "</span>);</span><br><span class="line">        <span class="keyword">while</span>(i &lt; MAX_COUNT)&#123;</span><br><span class="line">            <span class="comment">// 克隆</span></span><br><span class="line">            Mail mailClon = mail.clone();</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 设置称谓</span></span><br><span class="line">            mailClon.setAppellation(getRandString(<span class="number">5</span>) + <span class="string">"先生/女士"</span>);</span><br><span class="line">            <span class="comment">// 设置接收信箱</span></span><br><span class="line">            mailClon.setReceiver(getRandString(<span class="number">5</span>) + <span class="string">"@"</span> + getRandString(<span class="number">3</span>) + <span class="string">".com"</span>);</span><br><span class="line">            <span class="comment">// 设置邮件内容</span></span><br><span class="line">            mailClon.setContext(getRandString(<span class="number">20</span>));</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 发送邮件</span></span><br><span class="line">            sendMail(mailClon);</span><br><span class="line">            i++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 发送邮件</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">sendMail</span><span class="params">(Mail mail)</span></span>&#123;</span><br><span class="line">        <span class="comment">// 打印邮件相关信息</span></span><br><span class="line">        System.out.println(<span class="string">"标题："</span> + mail.getSubject() + <span class="string">"\t收件人："</span></span><br><span class="line">                + mail.getReceiver() + <span class="string">"\t内容："</span> + mail.getContent()</span><br><span class="line">                + <span class="string">"\t....发送成功！"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 模拟生成字符串</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> maxLength</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> String <span class="title">getRandString</span><span class="params">(<span class="keyword">int</span> maxLength)</span></span>&#123;</span><br><span class="line">        String source = <span class="string">"abcdefghijklmnopqrstuvwxyz"</span>;</span><br><span class="line">        <span class="comment">// 定义字符串缓冲区</span></span><br><span class="line">        StringBuilder sb = <span class="keyword">new</span> StringBuilder();</span><br><span class="line">        <span class="comment">// 定义随机数生成器</span></span><br><span class="line">        Random random = <span class="keyword">new</span> Random();</span><br><span class="line">        <span class="comment">// 循环</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i =<span class="number">0</span>; i &lt; maxLength; i++)&#123;</span><br><span class="line">            sb.append(source.charAt(random.nextInt(source.length())));</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> sb.toString();</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="5-3-原型模式的优缺点："><a href="#5-3-原型模式的优缺点：" class="headerlink" title="5.3 原型模式的优缺点："></a>5.3 原型模式的优缺点：</h3><p>优点：</p>
<p>•  使用原型模式创建对象比直接new一个对象更有效</p>
<p>•  隐藏制造新实例的复杂性</p>
<p>•  重复地创建相似对象时可以考虑使用原型模式</p>
<p>缺点：</p>
<p>•  每一个类必须配备一个克隆方法</p>
<p>•  深拷贝比较复杂</p>
<h3 id="5-5-适用场景："><a href="#5-5-适用场景：" class="headerlink" title="5.5 适用场景："></a>5.5 适用场景：</h3><p>•  复制对象的结构与数据；</p>
<p>•  希望对目标对象的修改不影响既有的原型对象；</p>
<p>•  创建对象成本较大的情况下。</p>
<h3 id="5-4-注意事项："><a href="#5-4-注意事项：" class="headerlink" title="5.4 注意事项："></a>5.4 注意事项：</h3><ul>
<li><p>使用原型模式复制对象不会调用类的构造方法。所以，单例模式与原型模式是冲突的，在使用时要特别注意。</p>
</li>
<li><p>在原型模式中，成员变量不能被final修饰</p>
</li>
<li><p>Object类的clone方法只会拷贝对象中的基本的数据类型，对于数组、容器对象、引用对象等都不会拷贝，这就是<strong>浅拷贝</strong>。如果要实现<strong>深拷贝</strong>，必须将原型模式中的数组、容器对象、引用对象等另行拷贝。</p>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Mail</span> <span class="keyword">implements</span> <span class="title">Cloneable</span></span>&#123;</span><br><span class="line">    <span class="comment">// 售收件人</span></span><br><span class="line">    <span class="keyword">private</span> String receiver;</span><br><span class="line">    <span class="comment">// 邮件名称</span></span><br><span class="line">    <span class="keyword">private</span> String subject;</span><br><span class="line">    <span class="comment">// 称谓</span></span><br><span class="line">    <span class="keyword">private</span> String appellation;</span><br><span class="line">    <span class="comment">// 邮件内容</span></span><br><span class="line">    <span class="keyword">private</span> String content;</span><br><span class="line">    <span class="comment">// 邮件尾部</span></span><br><span class="line">    <span class="keyword">private</span> String tail;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span>[] arr;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> Mail <span class="title">clone</span><span class="params">()</span>  </span>&#123;</span><br><span class="line">        Mail mail = <span class="keyword">null</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            mail = (Mail) <span class="keyword">super</span>.clone();</span><br><span class="line">            mail.arr = <span class="keyword">this</span>.arr.clone();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (CloneNotSupportedException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> mail;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 构造方法</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> advTemplete</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Mail</span><span class="params">(AdvTemplete advTemplete)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.content = advTemplete.getAdvContent();</span><br><span class="line">        <span class="keyword">this</span>.subject = advTemplete.getAdvSubject();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// ======================setter,getter=======================================</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">int</span>[] getArr() &#123;</span><br><span class="line">        <span class="keyword">return</span> arr;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setArr</span><span class="params">(<span class="keyword">int</span>[] arr)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.arr = arr;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setContent</span><span class="params">(String content)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.content = content;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getReceiver</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> receiver;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setReceiver</span><span class="params">(String receiver)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.receiver = receiver;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getSubject</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> subject;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setSubject</span><span class="params">(String subject)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.subject = subject;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getAppellation</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> appellation;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setAppellation</span><span class="params">(String appellation)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.appellation = appellation;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getContent</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> content;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setContext</span><span class="params">(String content)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.content = content;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getTail</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> tail;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setTail</span><span class="params">(String tail)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.tail = tail;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 设置邮件发送数</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">int</span> MAX_COUNT = <span class="number">6</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     *  模拟邮件发送</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> args</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 邮件创建</span></span><br><span class="line">        Mail mail = <span class="keyword">new</span> Mail(<span class="keyword">new</span> AdvTemplete());</span><br><span class="line">        mail.setTail(<span class="string">"    "</span>);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">int</span>[] arr = <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>&#125;;</span><br><span class="line">        mail.setArr(arr);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span>(i &lt; MAX_COUNT)&#123;</span><br><span class="line">            <span class="comment">// 克隆</span></span><br><span class="line">            Mail mailClon = mail.clone();</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 设置称谓</span></span><br><span class="line">            mailClon.setAppellation(getRandString(<span class="number">5</span>) + <span class="string">"先生/女士"</span>);</span><br><span class="line">            <span class="comment">// 设置接收信箱</span></span><br><span class="line">            mailClon.setReceiver(getRandString(<span class="number">5</span>) + <span class="string">"@"</span> + getRandString(<span class="number">3</span>) + <span class="string">".com"</span>);</span><br><span class="line">            <span class="comment">// 设置邮件内容</span></span><br><span class="line">            mailClon.setContext(getRandString(<span class="number">20</span>));</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span>(i == <span class="number">3</span>)&#123;</span><br><span class="line">                arr[<span class="number">0</span>] = <span class="number">9</span>;</span><br><span class="line">                arr[<span class="number">1</span>] = <span class="number">9</span>;</span><br><span class="line">                arr[<span class="number">2</span>] = <span class="number">9</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 发送邮件</span></span><br><span class="line">            sendMail(mailClon);</span><br><span class="line">            i++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 发送邮件</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">sendMail</span><span class="params">(Mail mail)</span></span>&#123;</span><br><span class="line">        <span class="comment">// 打印邮件相关信息</span></span><br><span class="line">        System.out.println(<span class="string">"标题："</span> + mail.getSubject() + <span class="string">"\t收件人："</span></span><br><span class="line">                + mail.getReceiver() + <span class="string">"\t内容："</span> + mail.getContent()</span><br><span class="line">                + <span class="string">"\t....发送成功！"</span>);</span><br><span class="line">        System.out.println(<span class="string">"arr: "</span> + mail.getArr() + Arrays.toString(mail.getArr()));</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 模拟生成字符串</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> maxLength</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> String <span class="title">getRandString</span><span class="params">(<span class="keyword">int</span> maxLength)</span></span>&#123;</span><br><span class="line">        String source = <span class="string">"abcdefghijklmnopqrstuvwxyz"</span>;</span><br><span class="line">        <span class="comment">// 定义字符串缓冲区</span></span><br><span class="line">        StringBuilder sb = <span class="keyword">new</span> StringBuilder();</span><br><span class="line">        <span class="comment">// 定义随机数生成器</span></span><br><span class="line">        Random random = <span class="keyword">new</span> Random();</span><br><span class="line">        <span class="comment">// 循环</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i =<span class="number">0</span>; i &lt; maxLength; i++)&#123;</span><br><span class="line">            sb.append(source.charAt(random.nextInt(source.length())));</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> sb.toString();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


      
    </div>
    <footer class="article-footer">
      <a data-url="http://codercheng.cn/2020/08/24/177230_23%E7%A7%8D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E8%AF%A6%E8%A7%A3%E7%AC%94%E8%AE%B0Part1/" data-id="cko3snvxs001xi8uogvh0gz8d" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2020/08/24/Java%204%E7%A7%8D%E5%BC%95%E7%94%A8%E5%85%B3%E7%B3%BB/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          Java 4种引用关系
        
      </div>
    </a>
  
  
</nav>

  
</article>

</section>
        
          <aside id="sidebar">
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">分类</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/Java/">Java</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/MySql/">MySql</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Netty/">Netty</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/SpringBoot/">SpringBoot</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/SpringCloud/">SpringCloud</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/SpringMVC/">SpringMVC</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Tomcat/">Tomcat</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Zookeeper/">Zookeeper</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E4%BD%9C%E4%B8%9A/">作业</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%88%86%E5%B8%83%E5%BC%8F%E8%B0%83%E5%BA%A6/">分布式调度</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E6%A1%86%E6%9E%B6/">框架</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E7%9F%A5%E8%AF%86/">知识</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">设计模式</a></li></ul>
    </div>
  </div>


  
    

  
    
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">归档</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2024/08/">八月 2024</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2022/09/">九月 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2022/08/">八月 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2022/04/">四月 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2022/02/">二月 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/11/">十一月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/06/">六月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/05/">五月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/04/">四月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/03/">三月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/02/">二月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/01/">一月 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/12/">十二月 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/11/">十一月 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/10/">十月 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/09/">九月 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/08/">八月 2020</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">最新文章</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2024/08/28/CentOS%E5%86%85%E5%AD%98cpu%E6%8E%92%E6%9F%A5/">CentOS内存cpu排查</a>
          </li>
        
          <li>
            <a href="/2022/09/22/Linux%20%E6%9F%A5%E7%9C%8B%E6%97%A5%E5%BF%97%E5%91%BD%E4%BB%A4/">Linux 查看日志命令</a>
          </li>
        
          <li>
            <a href="/2022/08/30/dubbo%20%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/">dubbo 常见问题</a>
          </li>
        
          <li>
            <a href="/2022/04/26/1%20%E6%BA%90%E7%A0%81%E7%AC%94%E8%AE%B0/">1 源码笔记</a>
          </li>
        
          <li>
            <a href="/2022/02/24/jvisualVM%20%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/">jvisualVM 使用笔记</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2024 CoderCheng<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//code.jquery.com/jquery-2.0.3.min.js"></script>


  
<link rel="stylesheet" href="/fancybox/jquery.fancybox.css">

  
<script src="/fancybox/jquery.fancybox.pack.js"></script>




<script src="/js/script.js"></script>




  </div>
</body>
</html>